package com.cxyjy.travelguide.controller;

import com.cxyjy.common.BusinessException;
import com.cxyjy.common.pojo.PageResult;
import com.cxyjy.common.util.*;
import com.cxyjy.travelguide.controller.vo.ArtifactCreateVO;
import com.cxyjy.travelguide.controller.vo.ArtifactQueryVO;
import com.cxyjy.travelguide.controller.vo.ArtifactRespVO;
import com.cxyjy.travelguide.dal.dataobject.ExternalArtifactDO;
import com.cxyjy.travelguide.service.Impl.BaiduAiImageServiceImpl;
import com.cxyjy.travelguide.service.TemplateImageService;
import com.google.common.util.concurrent.RateLimiter;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import static com.cxyjy.common.constants.CfyuiConstants.BAIDU_EXPECTED_IMAGE_EXTENSIONS;
import static com.cxyjy.common.util.JObjectUtil.*;
import static com.cxyjy.common.util.ResultCode.FACESWAP_EXCLUSIVE_PARAMETERS_PROVIDED;
import static com.cxyjy.common.util.ResultCode.NO_IMAGE_FOUNDED;
import static com.cxyjy.common.util.ResultUtil.error;
import static com.cxyjy.common.util.ResultUtil.success;

/**
 * 训练图图库管理
 * @Author: jony
 * @Date : 2025/4/29 15:17
 * @VERSION v1.0
 */
@RestController
public class TemplateImageController {
    @Resource
    TemplateImageService templateImageService;

    /**
     * 图片入库接口
     *
     * @param image      和url二选一
     * @param url        和image二选一
     * @param objectCode 文物编码，每张图片都要传
     * @param objectName 如果是新增的文物，则必须传（否则返回错误），因为要新增编码和文物名对应关系
     * @param classId1   范围1～999 表示城市
     * @param classId2   范围999～65535 表示景点
     * @return
     * @throws Exception
     */
    @PostMapping("/uploadTemplateImage")
    public JResponse uploadTemplateImage(@RequestParam(required = false) MultipartFile image, @RequestParam(required = false) String url, @RequestParam String objectCode,
                                         @RequestParam(required = false) String objectName, @RequestParam String classId1, @RequestParam String classId2) throws Exception {
        //二选一校验：必须传image或url，且不能同时传
        if ((image == null && url == null) || (image != null && url != null)) {
            return ResultUtil.error(FACESWAP_EXCLUSIVE_PARAMETERS_PROVIDED);
        }
        if (image != null) {
            if (image.isEmpty() || image.getOriginalFilename() == null) {
                return ResultUtil.error(NO_IMAGE_FOUNDED);
            }
            if (!JFileUtil.checkFileExtension(image, BAIDU_EXPECTED_IMAGE_EXTENSIONS)) {
                return ResultUtil.error(NO_IMAGE_FOUNDED);
            }
        }
        if (!(isValidPortNumber(classId1) && isValidPortNumber(classId2))) {
            return ResultUtil.error("未接收到正常的class_id，class_id应为1～65535之间的整数！");
        }
        if(!(isIntegerBetween(Integer.parseInt(classId1),1,999) &&
                isIntegerBetween(Integer.parseInt(classId2),1000,65535))) {
            return error("ID超出范围，城市ID为1～999，景区ID为1000～65535！");
        }
        if (image != null) {
            Map<String, Object> resultMap = templateImageService.uploadTemplateImage(image, objectCode, objectName, classId1, classId2);
            if (resultMap.keySet().iterator().next().equals("error")) {
                return new JResponse(objectToInt(resultMap.entrySet().iterator().next().getValue()), "");
            } else {
                return success("上传图片成功！文物编码为:" + objectCode + "cont_sign为:" + resultMap.get("contSign"));
            }

        } else {
            Map<String, Object> resultMap = templateImageService.uploadTemplateImage(url, objectCode, objectName, classId1, classId2);
            if (resultMap.keySet().iterator().next().equals("error")) {
                return new JResponse(objectToInt(resultMap.entrySet().iterator().next().getValue()), "");
            } else {
                return success("上传成功！文物编码为:" + objectCode + "，cont_sign为:" + resultMap.get("contSign"));
            }
        }
    }


    /**
     * 图片批量入库接口
     * @param images     和urls二选一（多个文件）
     * @param urls       和images二选一
     * @param objectCode 文物编码（所有图片共用）
     * @param objectName 如果是新增文物则必传（所有图片共用）
     * @param classId1   城市ID（所有图片共用）
     * @param classId2   景点ID（所有图片共用）
     * @return
     * @throws Exception
     */
    @PostMapping("/batchUploadTemplateImage")
    public JResponse batchUploadTemplateImage(
            @RequestParam(required = false) MultipartFile[] images,
            @RequestParam(required = false) String[] urls,
            @RequestParam String objectCode,
            @RequestParam(required = false) String objectName,
            @RequestParam String classId1,
            @RequestParam String classId2) throws Exception {

        // 二选一校验
        if ((images == null && urls == null) || (images != null && urls != null)) {
            return ResultUtil.error("参数错误，必须传且只传 images 或 urls 其中一种");
        }
        if (!(isValidPortNumber(classId1) && isValidPortNumber(classId2))) {
            return ResultUtil.error("未接收到正常的class_id，class_id应为1～65535之间的整数！");
        }
        if(!(isIntegerBetween(Integer.parseInt(classId1),1,999) &&
        isIntegerBetween(Integer.parseInt(classId2),1000,65535))) {
            return error("ID超出范围，城市ID为1～999，景区ID为1000～65535！");
        }
        // 获取要处理的数据列表
        List<Object> items = new ArrayList<>();
        if (images != null) {
            // 校验每个文件
            for (MultipartFile image : images) {
                if (image.isEmpty() || !JFileUtil.checkFileExtension(image, BAIDU_EXPECTED_IMAGE_EXTENSIONS)) {
                    return ResultUtil.error("图片格式不合法: " + image.getOriginalFilename());
                }
                items.add(image);
            }
        } else {
            Collections.addAll(items, urls);
        }

        // 限流控制（2QPS）
        RateLimiter rateLimiter = RateLimiter.create(2.0); // 每秒2个请求
        List<String> results = new ArrayList<>();

        for (Object item : items) {
            rateLimiter.acquire(); // 阻塞直到获得许可
            Map<String, Object> resultMap;
            if (item instanceof MultipartFile) {
                resultMap = templateImageService.uploadTemplateImage((MultipartFile) item, objectCode, objectName, classId1, classId2);
            } else {
                resultMap = templateImageService.uploadTemplateImage((String) item, objectCode, objectName, classId1, classId2);
            }
            if (resultMap.keySet().iterator().next().equals("error")) {
                return new JResponse(objectToInt(resultMap.entrySet().iterator().next().getValue()));
            }
            results.add("上传成功！文物编码为:" + objectCode + "，cont_sign为:" + resultMap.get("contSign"));
        }

        return success(results);
    }

    @PostMapping("/updateArtifact")
    public JResponse<Boolean> updateArtifact(@Valid @RequestBody ArtifactCreateVO saveVO) throws IOException {
        if(isEmpty(saveVO)){
            throw new BusinessException("修改内容有误，请检查后重试");
        }
        Integer classId1 = saveVO.getClassId1();
        Integer classId2 = saveVO.getClassId2();
        if (!(isValidPortNumber(classId1) && isValidPortNumber(classId2))) {
            return ResultUtil.error("未接收到正常的class_id，class_id应为1～65535之间的整数！");
        }
        if(!(isIntegerBetween(classId1,1,999) &&
                isIntegerBetween(classId2,1000,65535))) {
            return error("ID超出范围，城市ID为1～999，景区ID为1000～65535！");
        }
        return success(templateImageService.updateArtifact(saveVO));
    }
    /**
     * 删除文物，文物表和图片表还有百度图库里的图都删除，为物理删除
     *
     * @param id
     * @return
     * @throws IOException
     */
    @GetMapping("/deleteArtifact")
    public JResponse<List<String>>  deleteArtifact(@RequestParam Integer id) throws IOException {
        return success(templateImageService.deleteTemplateImageAndArtifact(
                templateImageService.getArtifact(id).getCode(),
                true));
    }

    /**
     * 删除文物，delArtifact为true时删除所有图片
     *
     * @param objectCode 文物编码
     * @param delArtifact 是否在百度图库中删除文物图片
     * @return
     * @throws IOException
     */
    @PostMapping("/deleteArtifactAndTemplateImage")
    public JResponse<List<String>> deleteTemplateImage(@RequestParam String objectCode,@RequestParam(required = false)boolean delArtifact) throws IOException {
        return success(templateImageService.deleteTemplateImageAndArtifact(objectCode,delArtifact));
    }

    /**
     * 所有文物分页接口
     *
     * @param queryVO
     * @return
     */
    @PostMapping("/pageArtifact")
    public JResponse<PageResult<ArtifactRespVO>> pageArtifact(@RequestBody ArtifactQueryVO queryVO){
        PageResult<ArtifactRespVO> externalArtifactDOPageResult = templateImageService.selectPage(queryVO);
        return success(externalArtifactDOPageResult);
    }

}
